package streams

import (
	"cmp"
	"slices"
	"strconv"
	"strings"
)

// OrderedStream 继承Stream接口，可以扩展cmp.Ordered类型的 Stream
type OrderedStream[T cmp.Ordered] interface {
	ComparableStream[T]
}

// 接口实现检查
var _ OrderedStream[int] = (*orderedStream[int])(nil)
var _ Stream[int] = (*orderedStream[int])(nil)

type orderedStream[T cmp.Ordered] struct {
	comparableStream[T]
}

func (my *orderedStream[T]) Sort() Stream[T] {
	slices.Sort(my.list)
	return my
}

func (my *orderedStream[T]) Join2(delimiter, prefix, suffix string) string {
	convertStrList := convert2SrList(my.list)
	return prefix + strings.Join(convertStrList, delimiter) + suffix
}

func convert2SrList(list any) []string {
	strList := make([]string, 0)
	switch arr := list.(type) {
	case []string:
		strList = arr
	case []int:
		for _, i := range arr {
			strList = append(strList, strconv.Itoa(i))
		}
	case []int8:
		for _, i := range arr {
			strList = append(strList, strconv.FormatInt(int64(i), 10))
		}
	case []int16:
		for _, i := range arr {
			strList = append(strList, strconv.FormatInt(int64(i), 10))
		}
	case []int32:
		for _, i := range arr {
			strList = append(strList, strconv.FormatInt(int64(i), 10))
		}
	case []int64:
		for _, i := range arr {
			strList = append(strList, strconv.FormatInt(i, 10))
		}
	case []uint:
		for _, i := range arr {
			strList = append(strList, strconv.FormatUint(uint64(i), 10))
		}
	case []uint8:
		for _, i := range arr {
			strList = append(strList, strconv.FormatUint(uint64(i), 10))
		}
	case []uint16:
		for _, i := range arr {
			strList = append(strList, strconv.FormatUint(uint64(i), 10))
		}
	case []uint32:
		for _, i := range arr {
			strList = append(strList, strconv.FormatUint(uint64(i), 10))
		}
	case []uint64:
		for _, i := range arr {
			strList = append(strList, strconv.FormatUint(i, 10))
		}
	case []float32:
		for _, i := range arr {
			strList = append(strList, strconv.FormatFloat(float64(i), 'f', -1, 32))
		}
	case []float64:
		for _, i := range arr {
			strList = append(strList, strconv.FormatFloat(i, 'f', -1, 64))
		}
	case []uintptr:
		panic("not support uintptr type for join")
	default:
		// nothing to do.
	}
	return strList
}
